#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
主界面模块
使用tkinter创建图形用户界面
"""

import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import threading
import os
from typing import List

from core.compressor import VideoCompressor
from utils.file_handler import (
    is_supported_video_file, 
    get_video_files_from_paths,
    format_file_size
)
from config.settings import (
    WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE,
    COMPRESSION_PRESETS, DEFAULT_PRESET
)


class MainWindow:
    """主窗口类"""
    
    def __init__(self):
        """初始化主窗口"""
        self.root = tk.Tk()
        self.compressor = VideoCompressor()
        self.selected_files: List[str] = []
        self.output_directory = ""
        self.is_compressing = False

        # 时间跟踪变量
        self.compression_start_time = None
        self.last_progress_time = None
        self.progress_history = []  # 存储进度历史用于预估
        self.current_file_index = 0
        self.total_files = 0
        
        self.setup_window()
        self.create_widgets()
        self.setup_layout()
    
    def setup_window(self):
        """设置窗口属性"""
        self.root.title(WINDOW_TITLE)
        self.root.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
        self.root.resizable(True, True)
        
        # 设置窗口图标（如果有的话）
        try:
            # self.root.iconbitmap("icon.ico")  # 可以添加图标
            pass
        except:
            pass
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 文件选择区域
        file_frame = ttk.LabelFrame(main_frame, text="文件选择", padding="10")
        file_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 选择文件按钮
        ttk.Button(file_frame, text="选择视频文件", 
                  command=self.select_files).grid(row=0, column=0, padx=(0, 10))
        
        # 选择输出目录按钮
        ttk.Button(file_frame, text="选择输出目录", 
                  command=self.select_output_directory).grid(row=0, column=1)
        
        # 文件列表
        self.file_listbox = tk.Listbox(file_frame, height=6)
        self.file_listbox.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(10, 0))

        # 添加拖拽提示
        self.file_listbox.insert(0, "拖拽MP4文件到此处，或点击上方按钮选择文件")
        self.file_listbox.config(foreground="gray")

        # 滚动条
        scrollbar = ttk.Scrollbar(file_frame, orient="vertical", command=self.file_listbox.yview)
        scrollbar.grid(row=1, column=2, sticky=(tk.N, tk.S), pady=(10, 0))
        self.file_listbox.configure(yscrollcommand=scrollbar.set)

        # 启用拖拽功能
        self.setup_drag_drop()
        
        # 压缩设置区域
        settings_frame = ttk.LabelFrame(main_frame, text="压缩设置", padding="10")
        settings_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 压缩预设选择
        ttk.Label(settings_frame, text="压缩质量:").grid(row=0, column=0, sticky=tk.W)

        self.preset_var = tk.StringVar(value=DEFAULT_PRESET)
        preset_combo = ttk.Combobox(settings_frame, textvariable=self.preset_var,
                                   state="readonly", width=30)
        preset_combo['values'] = [f"{key} - {preset['name']}"
                                 for key, preset in COMPRESSION_PRESETS.items()]
        preset_combo.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(10, 0))

        # 性能设置
        ttk.Label(settings_frame, text="性能模式:").grid(row=2, column=0, sticky=tk.W, pady=(10, 0))

        self.performance_var = tk.StringVar(value="balanced")
        performance_combo = ttk.Combobox(settings_frame, textvariable=self.performance_var,
                                       state="readonly", width=30)
        performance_combo['values'] = [
            "speed - 优先速度（可能占用更多CPU）",
            "balanced - 平衡模式（推荐）",
            "quality - 优先质量（较慢但更高质量）"
        ]
        performance_combo.set("balanced - 平衡模式（推荐）")
        performance_combo.grid(row=2, column=1, sticky=(tk.W, tk.E), padx=(10, 0), pady=(10, 0))

        # 硬件信息显示
        self.hardware_info_var = tk.StringVar(value="正在检测硬件...")
        self.hardware_info_label = ttk.Label(settings_frame, textvariable=self.hardware_info_var,
                                            foreground="blue", font=("", 8))
        self.hardware_info_label.grid(row=3, column=0, columnspan=2, sticky=tk.W, pady=(5, 0))

        # 异步检测硬件信息
        self.root.after(100, self.detect_hardware_info)
        
        # 输出目录显示
        ttk.Label(settings_frame, text="输出目录:").grid(row=1, column=0, sticky=tk.W, pady=(10, 0))
        self.output_label = ttk.Label(settings_frame, text="未选择", foreground="gray")
        self.output_label.grid(row=1, column=1, sticky=(tk.W, tk.E), padx=(10, 0), pady=(10, 0))
        
        # 操作按钮区域
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=2, column=0, columnspan=2, pady=(0, 10))
        
        self.start_button = ttk.Button(button_frame, text="开始压缩", 
                                      command=self.start_compression)
        self.start_button.pack(side=tk.LEFT, padx=(0, 10))
        
        self.stop_button = ttk.Button(button_frame, text="停止压缩", 
                                     command=self.stop_compression, state="disabled")
        self.stop_button.pack(side=tk.LEFT)
        
        # 进度区域
        progress_frame = ttk.LabelFrame(main_frame, text="压缩进度", padding="10")
        progress_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))

        # 主要进度信息
        self.progress_var = tk.StringVar(value="准备就绪")
        self.progress_label = ttk.Label(progress_frame, textvariable=self.progress_var)
        self.progress_label.grid(row=0, column=0, sticky=(tk.W, tk.E))

        # 进度条
        self.progress_bar = ttk.Progressbar(progress_frame, mode='determinate', maximum=100)
        self.progress_bar.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(10, 0))

        # 详细信息框架
        detail_frame = ttk.Frame(progress_frame)
        detail_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=(10, 0))
        detail_frame.columnconfigure(0, weight=1)
        detail_frame.columnconfigure(1, weight=1)

        # 剩余时间显示
        self.time_remaining_var = tk.StringVar(value="剩余时间: --")
        self.time_remaining_label = ttk.Label(detail_frame, textvariable=self.time_remaining_var)
        self.time_remaining_label.grid(row=0, column=0, sticky=tk.W)

        # 已用时间显示
        self.elapsed_time_var = tk.StringVar(value="已用时间: --")
        self.elapsed_time_label = ttk.Label(detail_frame, textvariable=self.elapsed_time_var)
        self.elapsed_time_label.grid(row=0, column=1, sticky=tk.E)

        # 速度信息显示
        self.speed_var = tk.StringVar(value="处理速度: --")
        self.speed_label = ttk.Label(detail_frame, textvariable=self.speed_var)
        self.speed_label.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(5, 0))
        
        # 结果显示区域
        result_frame = ttk.LabelFrame(main_frame, text="压缩结果", padding="10")
        result_frame.grid(row=4, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        self.result_text = tk.Text(result_frame, height=8, wrap=tk.WORD)
        self.result_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        result_scrollbar = ttk.Scrollbar(result_frame, orient="vertical", 
                                        command=self.result_text.yview)
        result_scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
        self.result_text.configure(yscrollcommand=result_scrollbar.set)
    
    def setup_layout(self):
        """设置布局权重"""
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)

        # 主框架内的权重设置
        main_frame = self.root.grid_slaves()[0]
        main_frame.columnconfigure(0, weight=1)
        main_frame.rowconfigure(4, weight=1)  # 结果区域可扩展

    def setup_drag_drop(self):
        """设置拖拽功能（简化版本）"""
        # 由于tkinter的拖拽功能比较复杂，这里提供一个简化的实现
        # 用户可以通过双击文件列表来添加文件
        self.file_listbox.bind('<Double-Button-1>', lambda e: self.select_files())

        # 添加右键菜单
        self.setup_context_menu()

    def setup_context_menu(self):
        """设置右键菜单"""
        self.context_menu = tk.Menu(self.root, tearoff=0)
        self.context_menu.add_command(label="添加文件", command=self.select_files)
        self.context_menu.add_command(label="清空列表", command=self.clear_file_list)
        self.context_menu.add_separator()
        self.context_menu.add_command(label="移除选中", command=self.remove_selected_file)

        # 绑定右键菜单
        self.file_listbox.bind('<Button-3>', self.show_context_menu)

    def show_context_menu(self, event):
        """显示右键菜单"""
        try:
            self.context_menu.tk_popup(event.x_root, event.y_root)
        finally:
            self.context_menu.grab_release()

    def clear_file_list(self):
        """清空文件列表"""
        self.selected_files = []
        self.update_file_list()

    def remove_selected_file(self):
        """移除选中的文件"""
        selection = self.file_listbox.curselection()
        if selection and self.selected_files:
            index = selection[0]
            if 0 <= index < len(self.selected_files):
                self.selected_files.pop(index)
                self.update_file_list()
    
    def select_files(self):
        """选择视频文件"""
        files = filedialog.askopenfilenames(
            title="选择MP4视频文件",
            filetypes=[("MP4文件", "*.mp4"), ("所有文件", "*.*")]
        )
        
        if files:
            # 筛选支持的视频文件
            video_files = [f for f in files if is_supported_video_file(f)]
            
            if video_files:
                self.selected_files = video_files
                self.update_file_list()
            else:
                messagebox.showwarning("警告", "未选择有效的MP4视频文件")
    
    def select_output_directory(self):
        """选择输出目录"""
        directory = filedialog.askdirectory(title="选择输出目录")
        
        if directory:
            self.output_directory = directory
            self.output_label.config(text=directory, foreground="black")
    
    def update_file_list(self):
        """更新文件列表显示"""
        self.file_listbox.delete(0, tk.END)

        if not self.selected_files:
            # 显示提示信息
            self.file_listbox.insert(0, "拖拽MP4文件到此处，或点击上方按钮选择文件")
            self.file_listbox.config(foreground="gray")
        else:
            self.file_listbox.config(foreground="black")
            for file_path in self.selected_files:
                filename = os.path.basename(file_path)
                try:
                    size = os.path.getsize(file_path)
                    size_str = format_file_size(size)
                    self.file_listbox.insert(tk.END, f"{filename} ({size_str})")
                except:
                    self.file_listbox.insert(tk.END, filename)
    
    def get_selected_preset(self) -> str:
        """获取选中的压缩预设"""
        preset_text = self.preset_var.get()
        return preset_text.split(" - ")[0]
    
    def start_compression(self):
        """开始压缩"""
        if not self.selected_files:
            messagebox.showwarning("警告", "请先选择要压缩的视频文件")
            return
        
        if not self.output_directory:
            messagebox.showwarning("警告", "请先选择输出目录")
            return
        
        # 启动压缩线程
        self.is_compressing = True
        self.compressor.is_compressing = True  # 同步压缩器状态
        self.start_button.config(state="disabled")
        self.stop_button.config(state="normal")

        # 设置进度条为确定模式
        self.progress_bar.config(mode='determinate')
        self.progress_bar['value'] = 0

        thread = threading.Thread(target=self.compression_worker)
        thread.daemon = True
        thread.start()
    
    def stop_compression(self):
        """停止压缩"""
        self.is_compressing = False
        self.compressor.stop_compression()
        self.reset_ui_state()
    
    def compression_worker(self):
        """压缩工作线程"""
        try:
            import time

            preset = self.get_selected_preset()

            # 初始化时间跟踪
            self.compression_start_time = time.time()
            self.last_progress_time = self.compression_start_time
            self.progress_history = []
            self.total_files = len(self.selected_files)
            self.current_file_index = 0

            # 设置进度回调
            def progress_callback(progress, message):
                self.update_progress_with_time(progress, message)

            self.compressor.set_progress_callback(progress_callback)

            self.update_progress("开始批量压缩...")
            self.clear_results()
            self.reset_progress_display()

            # 使用批量压缩功能
            batch_result = self.compressor.compress_batch(
                self.selected_files, self.output_directory, preset)

            # 显示详细结果
            self.add_result("=" * 50)
            self.add_result("压缩完成!")
            self.add_result("=" * 50)
            self.add_result(f"总文件数: {batch_result['total_files']}")
            self.add_result(f"成功: {batch_result['successful']}")
            self.add_result(f"失败: {batch_result['failed']}")

            if batch_result['total_original_size'] > 0:
                self.add_result(f"总原始大小: {format_file_size(batch_result['total_original_size'])}")
                self.add_result(f"总压缩后大小: {format_file_size(batch_result['total_compressed_size'])}")
                self.add_result(f"总体压缩比: {batch_result['total_compression_ratio']:.1f}%")
                saved_size = batch_result['total_original_size'] - batch_result['total_compressed_size']
                self.add_result(f"节省空间: {format_file_size(saved_size)}")

            self.add_result("")
            self.add_result("详细结果:")
            self.add_result("-" * 30)

            for result in batch_result['results']:
                if result['status'] == 'success':
                    self.add_result(f"✓ {result['file']}")
                    self.add_result(f"  原始: {format_file_size(result['original_size'])}")
                    self.add_result(f"  压缩后: {format_file_size(result['compressed_size'])}")
                    self.add_result(f"  节省: {result['compression_ratio']:.1f}%")
                else:
                    self.add_result(f"✗ {result['file']}")
                    self.add_result(f"  错误: {result['error']}")
                self.add_result("")

            if self.is_compressing:
                self.update_progress("所有文件压缩完成!")
                # 显示完成通知
                self.root.after(0, lambda: messagebox.showinfo(
                    "压缩完成",
                    f"成功压缩 {batch_result['successful']} 个文件\n"
                    f"失败 {batch_result['failed']} 个文件\n"
                    f"总体压缩比: {batch_result.get('total_compression_ratio', 0):.1f}%"
                ))
            else:
                self.update_progress("压缩已停止")

        except Exception as e:
            self.update_progress(f"压缩出错: {str(e)}")
            self.add_result(f"错误: {str(e)}")
            self.root.after(0, lambda: messagebox.showerror("压缩错误", str(e)))

        finally:
            self.root.after(0, self.reset_ui_state)
    
    def update_progress(self, message: str):
        """更新进度显示"""
        self.root.after(0, lambda: self.progress_var.set(message))

    def update_progress_with_time(self, progress: float, message: str):
        """更新进度显示并计算时间预估"""
        import time

        current_time = time.time()

        # 记录进度历史
        if self.compression_start_time:
            elapsed_time = current_time - self.compression_start_time
            self.progress_history.append((elapsed_time, progress))

            # 只保留最近的进度记录（用于更准确的预估）
            if len(self.progress_history) > 20:
                self.progress_history = self.progress_history[-20:]

        # 更新主要进度信息
        self.root.after(0, lambda: self.progress_var.set(message))
        self.root.after(0, lambda: self.progress_bar.config(value=progress))

        # 计算并更新时间信息
        if self.compression_start_time and len(self.progress_history) >= 2:
            self._update_time_estimates(progress, current_time)

    def _update_time_estimates(self, progress: float, current_time: float):
        """计算并更新时间预估"""
        elapsed_time = current_time - self.compression_start_time

        # 格式化已用时间
        elapsed_str = self._format_time(elapsed_time)

        # 计算剩余时间
        if progress > 0 and progress < 100:
            # 使用最近几个进度点计算平均速度
            if len(self.progress_history) >= 3:
                recent_history = self.progress_history[-5:]  # 最近5个点
                time_diff = recent_history[-1][0] - recent_history[0][0]
                progress_diff = recent_history[-1][1] - recent_history[0][1]

                if time_diff > 0 and progress_diff > 0:
                    # 基于最近速度预估
                    speed = progress_diff / time_diff  # 每秒进度
                    remaining_progress = 100 - progress
                    remaining_time = remaining_progress / speed
                else:
                    # 基于总体平均速度预估
                    speed = progress / elapsed_time
                    remaining_progress = 100 - progress
                    remaining_time = remaining_progress / speed
            else:
                # 基于总体平均速度预估
                speed = progress / elapsed_time
                remaining_progress = 100 - progress
                remaining_time = remaining_progress / speed

            remaining_str = self._format_time(remaining_time)

            # 计算处理速度（每秒处理的百分比）
            speed_str = f"{speed:.2f}%/秒" if speed > 0 else "--"
        else:
            remaining_str = "--"
            speed_str = "--"

        # 更新UI显示
        self.root.after(0, lambda: self.elapsed_time_var.set(f"已用时间: {elapsed_str}"))
        self.root.after(0, lambda: self.time_remaining_var.set(f"剩余时间: {remaining_str}"))
        self.root.after(0, lambda: self.speed_var.set(f"处理速度: {speed_str}"))

    def _format_time(self, seconds: float) -> str:
        """格式化时间显示"""
        if seconds < 0:
            return "--"

        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        secs = int(seconds % 60)

        if hours > 0:
            return f"{hours:02d}:{minutes:02d}:{secs:02d}"
        else:
            return f"{minutes:02d}:{secs:02d}"

    def reset_progress_display(self):
        """重置进度显示"""
        self.root.after(0, lambda: self.progress_bar.config(value=0))
        self.root.after(0, lambda: self.elapsed_time_var.set("已用时间: --"))
        self.root.after(0, lambda: self.time_remaining_var.set("剩余时间: --"))
        self.root.after(0, lambda: self.speed_var.set("处理速度: --"))
    
    def add_result(self, text: str):
        """添加结果文本"""
        self.root.after(0, lambda: self.result_text.insert(tk.END, text + "\n"))
        self.root.after(0, lambda: self.result_text.see(tk.END))
    
    def clear_results(self):
        """清空结果显示"""
        self.root.after(0, lambda: self.result_text.delete(1.0, tk.END))
    
    def reset_ui_state(self):
        """重置UI状态"""
        self.is_compressing = False
        self.start_button.config(state="normal")
        self.stop_button.config(state="disabled")

        # 重置进度条为不确定模式
        self.progress_bar.stop()
        self.progress_bar.config(mode='indeterminate')

        # 重置时间跟踪变量
        self.compression_start_time = None
        self.progress_history = []
    
    def detect_hardware_info(self):
        """检测并显示硬件信息"""
        try:
            encoder = self.compressor.best_encoder
            gpu_type = self.compressor.gpu_type

            if gpu_type:
                if gpu_type == "nvidia":
                    hw_info = "🚀 检测到NVIDIA GPU加速"
                elif gpu_type == "amd":
                    hw_info = "🚀 检测到AMD GPU加速"
                elif gpu_type == "intel":
                    hw_info = "🚀 检测到Intel GPU加速"
                else:
                    hw_info = "🚀 检测到GPU加速"
            else:
                hw_info = "💻 使用CPU编码（推荐选择'极速压缩'模式）"

            hw_info += f" | 编码器: {encoder}"
            self.hardware_info_var.set(hw_info)

        except Exception as e:
            self.hardware_info_var.set("⚠️ 硬件检测失败，使用默认设置")

    def get_performance_mode(self) -> str:
        """获取性能模式"""
        performance_text = self.performance_var.get()
        if "speed" in performance_text:
            return "speed"
        elif "quality" in performance_text:
            return "quality"
        else:
            return "balanced"

    def run(self):
        """运行主窗口"""
        self.root.mainloop()
